﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TakePhotoTogether.Communication;

namespace TakePhotoTogetherTest.Mock
{
    class MockSocketManager : SocketManager
    {
        private Dictionary<int, IRemoteDataListener> _remoteDataListeners = null;

        /// <summary> Singleton instance </summary>
        private static MockSocketManager _instance = null;
        private bool sendingLoopActivate = false;

        private Random rnd = new Random();

        /// <summary>
        /// Singleton method
        /// </summary>
        /// <returns></returns>
        public static MockSocketManager GetSocketManager()
        {
            if (_instance == null)
            {
                _instance = new MockSocketManager();
            }
            return _instance;
        }

        public MockSocketManager() : base()
        {
            
        }

        /// <summary>
        /// Add a listener to receive messages that come from socket
        /// </summary>
        /// <param name="listener">A class that implements IRemoteDataListener</param>
        /// <param name="messageType">Filters which message will be forward to listener</param>
        public void AddDataListener(IRemoteDataListener listener, int messageType)
        {
            // Shouldn't add a key twice
            if (_remoteDataListeners == null)
            {
                _remoteDataListeners = new Dictionary<int, IRemoteDataListener>();
            }

            if (!_remoteDataListeners.ContainsKey(messageType))
            {
                _remoteDataListeners.Add(messageType, listener);
            }
        }

        public override void SendDataToListener(byte[] data, int messageType)
        {
            if (_remoteDataListeners != null && _remoteDataListeners[messageType] != null)
            {
                PayloadData payload = DataPacketFactory.GetPayload(messageType, data);

                _remoteDataListeners[messageType].ReceiveData(payload);
            }
        } 

        /// <summary>
        /// Loop that handles received packets
        /// </summary>
        protected override async Task packetSendingLoop()
        {
            Debug.WriteLine("PacketSendingLoop");

            if (sendingLoopActivate)
                return;

            sendingLoopActivate = true;
            try
            {
                while (dataQueue.Count() > 0)
                {
                    DataPacket packet = dataQueue.Dequeue();

                    SendDataToListener(packet.Payload.ToBytes(), packet.MessageType);

                    await Task.Delay(rnd.Next(10,100));
                }
                sendingLoopActivate = false;
            }
            catch (Exception exception)
            {
                Debug.WriteLine("MockSocketManager::packetSendingLoop - error send: " + exception.HResult.ToString("X2") + " | " + exception.Message);
            }
        }
    }
}
